package cn.sany.cterminal.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.sany.cterminal.common.constants.CterminalConst;
import cn.sany.cterminal.dao.*;
import cn.sany.cterminal.entity.*;
import cn.sany.cterminal.entity.request.StatisticQueryParam;
import cn.sany.cterminal.service.RealtimeInfoService;
import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 *
 * @Project : sany
 * @Package : cn.sany.cterminal.service
 * @Class : StatisticService
 * @Description : 实时信息service
 * @author : zhouxing
 * @CreateDate : 2020-09-14 09:54:00
 * @version : V0.5
 * @Copyright : 2020 sany.com Inc. All rights reserved.
 * @Reviewed :
 * @UpateLog :    Name    Date    Reason/Contents
 *             ---------------------------------------
 *                ****    ****    ****
 *
 */
@Service
@Slf4j
public class RealtimeInfoServiceImpl implements RealtimeInfoService {
    @Autowired(required = false)
    StatisticHistoryDao statisticHistoryDao;
    @Autowired(required = false)
    VehicleInfoDao vehicleInfoDao;
    @Autowired(required = false)
    VehicleOperateRecordDao vehicleOperateRecordDao;
    @Autowired(required = false)
    RealtimeInfoDao realtimeInfoDao;
    /**
     *
     * @Method : getRealTimeInfo
     * @Description :获取实时数据
     * @return : java.util.List
     * @author : zhouxing
     * @CreateDate : 2020-09-14 13:40:11
     *
     */
    @Override
    public Map getRealTimeInfo() {
        HashMap<String,Map> result = new HashMap();
        Integer registerNum = vehicleOperateRecordDao.countVehicleByType(CterminalConst.OperateType.REGISTER);
        Integer logOutNum = vehicleOperateRecordDao.countVehicleByType(CterminalConst.OperateType.LOGOUT);
        Integer yesterdayRegisterNum = vehicleOperateRecordDao.countYesterdayVehicleByType(CterminalConst.OperateType.REGISTER);
        Integer yesterdayLogOutNum = vehicleOperateRecordDao.countYesterdayVehicleByType(CterminalConst.OperateType.LOGOUT);
        int deviceNum = vehicleInfoDao.selectVehicleByEnableState(CterminalConst.EnableState.ABLE).size();
        result.put("totalDevice",createTotalDevice(registerNum,logOutNum,deviceNum));
        result.put("registerDevice",createRegisterDevice(registerNum,yesterdayRegisterNum));
        result.put("onlineDevice",createOnlineDevice(deviceNum));
        result.put("faultDevice",createFaultDevice());
        result.put("loginOutDevice",createLoginOutDevice(logOutNum,yesterdayLogOutNum));
        return result;
    }
    /**
     *
     * @Method : getDeviceLocation
     * @Description : 获取所有设备位置信息接口
     * @return : cn.sany.cterminal.common.CommonReturn
     * @author : zhouxing
     * @CreateDate : 2020-09-14 17:50:54
     *
     */
    @Override
    public List getDeviceLocation() {
        List<VehicleInfo> vehicleList = vehicleInfoDao.selectVehicleByEnableState(CterminalConst.EnableState.ABLE);
        List<RealtimeInfo> realtimeInfos = realtimeInfoDao.selectAll();
        Map<Integer, RealtimeInfo> realtimeInfoMap = realtimeInfos.stream().collect(Collectors.toMap(RealtimeInfo::getVehicleId, RealtimeInfo -> RealtimeInfo));
        List<DeviceLocationVo> result = new ArrayList();
        for (VehicleInfo vehicleInfo : vehicleList) {
            DeviceLocationVo deviceLocationVo = new DeviceLocationVo();
            deviceLocationVo.setDeviceId(vehicleInfo.getVinNumber());
            RealtimeInfo realtimeInfo = realtimeInfoMap.get(vehicleInfo.getId());
            if (realtimeInfo != null){
                deviceLocationVo.setLatitude(realtimeInfo.getLatitude());
                deviceLocationVo.setLongitude(realtimeInfo.getLongitude());
            }else  {
                deviceLocationVo.setLatitude("");
                deviceLocationVo.setLongitude("");
            }
            result.add(deviceLocationVo);
        }
        return result;
    }

    private Map createFaultDevice() {
        List<RealtimeInfo> realtimeInfos = realtimeInfoDao.selectAll();
        Integer faultNum =  0;
        for (RealtimeInfo realtimeInfo : realtimeInfos) {
            if(realtimeInfo.getFaultNumber() != 0 ){
                faultNum += 1;
            }
        }
        StatisticQueryParam statisticQueryParam = new StatisticQueryParam();
        statisticQueryParam.setEndTime(new Date());
        statisticQueryParam.setStartTime(DateUtil.yesterday());
        Integer yesterdayFaultNum = statisticHistoryDao.selectYesterdayFaultNum();

        HashMap result = new HashMap();
        result.put("faultNum",faultNum);
        if(faultNum >= yesterdayFaultNum){
            result.put("changeNum",faultNum - yesterdayFaultNum);
            result.put("changeFlag",true);
        }else{
            result.put("changeNum",yesterdayFaultNum - faultNum);
            result.put("changeFlag",false);
        }
        return result;
    }

    private Map createLoginOutDevice(Integer logOutNum, Integer yesterdayLogOutNum) {
        HashMap result = new HashMap();
        result.put("loginOutNum",vehicleInfoDao.selectVehicleByEnableState(CterminalConst.EnableState.EN_ABLE).size());
        if(logOutNum >= yesterdayLogOutNum){
            result.put("changeNum",logOutNum - yesterdayLogOutNum);
            result.put("changeFlag",true);
        }else{
            result.put("changeNum",yesterdayLogOutNum - logOutNum);
            result.put("changeFlag",false);
        }
        return result;
    }

    private Map createOnlineDevice(Integer deviceNum) {
        Integer onlineNum =  realtimeInfoDao.selectOnLineNum();
        Integer yesterdayOnlineNum =  statisticHistoryDao.selectYesterdayOnLineNum();
        HashMap result = new HashMap();
        result.put("onlineNum",onlineNum*100/deviceNum);
        if(onlineNum >= yesterdayOnlineNum){
            result.put("changeNum",(onlineNum - yesterdayOnlineNum)*100/deviceNum);
            result.put("changeFlag",true);
        }else{
            result.put("changeNum",(yesterdayOnlineNum - onlineNum)*100/deviceNum);
            result.put("changeFlag",false);
        }
        return result;
    }

    private Map createRegisterDevice(Integer registerNum, Integer yesterdayRegisterNum) {
        HashMap result = new HashMap();
        result.put("registerNum",registerNum);
        if(registerNum >= yesterdayRegisterNum){
            result.put("changeNum",registerNum - yesterdayRegisterNum);
            result.put("changeFlag",true);
        }else{
            result.put("changeNum",yesterdayRegisterNum - registerNum);
            result.put("changeFlag",false);
        }
        return result;
    }

    private Map createTotalDevice(Integer registerNum,Integer logOutNum,Integer deviceNum){
        HashMap result = new HashMap();
        result.put("deviceNum",deviceNum);
        if(registerNum >= logOutNum){
            result.put("changeNum",registerNum - logOutNum);
            result.put("changeFlag",true);
        }else{
            result.put("changeNum",logOutNum - registerNum);
            result.put("changeFlag",false);
        }
        return result;
    }
}
